home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / msdos / ctest259.zip / DHRY.PAS < prev    next >
Pascal/Delphi Source File  |  1992-04-05  |  28KB  |  764 lines

  1. {$A+,B-,D-,E+,F-,G-,I-,L-,N+,O-,R-,S-,V-,X-}
  2. {$M 4096,0,655360}
  3. UNIT Dhry;
  4.  
  5. INTERFACE
  6.  
  7. FUNCTION Dhrystones (Index: DOUBLE): DOUBLE;
  8.  
  9. IMPLEMENTATION
  10.  
  11. USES Time;
  12.  
  13. (*
  14.  ****************************************************************************
  15.  *
  16.  *                   "DHRYSTONE" Benchmark Program
  17.  *                   -----------------------------
  18.  *
  19.  *  Version:    Pascal, Version 2.1
  20.  *
  21.  *  File:       dhry.p
  22.  *
  23.  *  Date:       May 25, 1988
  24.  *
  25.  *  Author:     Reinhold P. Weicker
  26.  *                      Siemens AG, E STE 35
  27.  *                      Postfach 3220
  28.  *                      8520 Erlangen
  29.  *                      Germany (West)
  30.  *                              Phone:  [xxx-49]-9131-7-20330
  31.  *                                      (8-17 Central European Time)
  32.  *                              Usenet: ..!mcvax!unido!estevax!weicker
  33.  *
  34.  *              Original Version (in Ada) published in
  35.  *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
  36.  *              pp. 1013 - 1030, together with the statistics
  37.  *              on which the distribution of statements etc. is based,
  38.  *
  39.  *              This version uses calls to the Pascal runtime library of the
  40.  *              Berkeley UNIX system (4.3 bsd) for time measurement.
  41.  *              For measurements on other systems, these calls need to be
  42.  *              modified.
  43.  *
  44.  *  Collection of Results:
  45.  *              Reinhold Weicker (address see above) and
  46.  *
  47.  *              Rick Richardson
  48.  *              PC Research. Inc.
  49.  *              94 Apple Orchard Drive
  50.  *              Tinton Falls, NJ 07724
  51.  *                      Phone:  (201) 834-1378 (9-17 EST)
  52.  *                      Usenet: ...!seismo!uunet!pcrat!rick
  53.  *
  54.  *      Please send results to Rick Richardson and/or Reinhold Weicker.
  55.  *      Complete information should be given on hardware and software used.
  56.  *      Hardware information includes: Machine type, CPU, type and size
  57.  *      of caches; for microprocessors: clock frequency, memory speed
  58.  *      (number of wait states).
  59.  *      Software information includes: Compiler (and runtime library)
  60.  *      manufacturer and version, compilation switches, OS version.
  61.  *      The Operating System version may give an indication about the
  62.  *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
  63.  *
  64.  *      The complete output generated by the program should be mailed
  65.  *      such that at least some checks for correctness can be made.
  66.  *
  67.  ****************************************************************************
  68.  *
  69.  *  History:    This version Pascal/2.1 has been made for two reasons:
  70.  *
  71.  *              1) There is a need for a common Pascal version of
  72.  *              Dhrystone. Although translation from the published (Ada)
  73.  *              version to Pascal is straightforward in most aspects,
  74.  *              there are cases where it may not be obvious to everyone.
  75.  *              There should be, as far as possible, only one Pascal version
  76.  *              of Dhrystone such that results can be compared without
  77.  *              restrictions. Also, a Pascal version of Dhrystone has not yet
  78.  *              found a network distribution comparable to the C version
  79.  *              (version 1.1) distributed by Rick Richardson.
  80.  *
  81.  *              2) As far as it is possible without changes to the Dhrystone
  82.  *              statistics, optimizing compilers should be prevented from
  83.  *              removing significant statements.
  84.  *
  85.  *              This Pascal version 2.1 has been made consistent with the
  86.  *              C version 2.1; therefore the acknowledgments for the C version
  87.  *              are due for the Pascal version as well: I thank
  88.  *              Rick Richardson (Tinton Falls, NJ), Chaim Benedelac (Nat.
  89.  *              Semi.), David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
  90.  *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
  91.  *              for their help with comments on earlier versions of the
  92.  *              benchmark.
  93.  *
  94.  *  Changes:    In the initialization part, this version differs
  95.  *              from the Pascal version previously distributed by Reinhold
  96.  *              Weicker, the number of runs through Dhrystone is obtained
  97.  *              interactively from the terminal. Output of the result
  98.  *              has been changed to conform to the C version (2.1).
  99.  *              The changes in the initialization part and in the printing
  100.  *              of the result have no impact on performance measurement
  101.  *              since they are outside the measaurement loop.
  102.  *
  103.  *              Inside the measurement loop, this version follows the
  104.  *              version previously distributed by Reinhold Weicker.
  105.  *              As a correction to the published version, a statement
  106.  *              initializing Array2Glob [8,7] (outside the measurement
  107.  *              loop) has been added. Otherwise, this array element would
  108.  *              have an undefined value.
  109.  *
  110.  *              At several places in the benchmark, code has been added,
  111.  *              but within the measurement loop only in branches that
  112.  *              are not executed. The intention is that optimizing compilers
  113.  *              should be prevented from moving code out of the measurement
  114.  *              loop, or from removing code altogether. Since the statements
  115.  *              that are executed within the measurement loop have NOT been
  116.  *              changed, all numbers defining the "Dhrystone distribution"
  117.  *              (distribution of statements, operand types and locality)
  118.  *              still hold. Except for sophisticated optimizing compilers,
  119.  *              execution times for this version should be the same as
  120.  *              for previous versions.
  121.  *
  122.  *              Since it has proven difficult to subtract the time for the
  123.  *              measurement loop overhead in a correct way, the loop check
  124.  *              has been made a part of the benchmark. This does have
  125.  *              an impact - though a very minor one - on the distribution
  126.  *              statistics which have been updated for this version.
  127.  *
  128.  *              All changes within the measurement loop are described
  129.  *              and discussed in the companion paper "Rationale for
  130.  *              Dhrystone version 2".
  131.  *
  132.  *              Because of the self-imposed limitation that the order and
  133.  *              distribution of the executed statements should not be
  134.  *              changed, there are still cases where optimizing compilers
  135.  *              may not generate code for some statements. To a certain
  136.  *              degree, this is unavoidable for small synthetic benchmarks.
  137.  *              Users of the benchmark are advised to check code listings
  138.  *              whether code is generated for all statements of Dhrystone.
  139.  *
  140.  *              Version 2.1 is identical to version 2.0 distributed via
  141.  *              the UNIX network Usenet in March 1988 except that it corrects
  142.  *              some minor deficiencies that were found by users of version 2.0.
  143.  *              The only change within the measurement loop is that a
  144.  *              non-executed "else" part was added to the "if" statement in
  145.  *              Func3, and a non-executed "else" part removed from Proc3.
  146.  *
  147.  ***************************************************************************
  148.  *
  149.  *  Compilation model and measurement (IMPORTANT):
  150.  *
  151.  *  This program contains the Dhrystone program, including measurement setup,
  152.  *  in one file. The original (Ada) program contained three packages,
  153.  *  - a package with global type definitions,
  154.  *  - Pack_1, containing the main program (Proc_0 in Ada) and procedures
  155.  *            Proc_1, ... , Proc_5,
  156.  *  - Pack_2, containing Proc_6, ... , Proc_8, Func_1, ..., Func_3.
  157.  *  Since ISO/ANSI Standard Pascal provides no means to express separate
  158.  *  compilation (although many Pascal implementations provide such a feature),
  159.  *  it is not possible to formulate a portable Pascal version with the program
  160.  *  in several modules, corresponding more closely to the Ada and C versions.
  161.  *  Therefore, no attempt has been made to construct a Pascal version with
  162.  *  the program consisting of several modules.
  163.  *
  164.  *  This difference may impact execution time because the compiler can
  165.  *  perform more data flow analysis for a single-module program;
  166.  *  sophisticated compilers may be able to suppress code generation for
  167.  *  some parts of the program.
  168.  *  Users should check machine code listings generated by the compiler
  169.  *  to ensure that code is generated for all parts of the program.
  170.  *
  171.  *  The following "ground rules" apply for measurements:
  172.  *  - No procedure merging
  173.  *  - Otherwise, compiler optimizations are allowed but should be indicated
  174.  *  See the companion paper "Rationale for Dhrystone Version 2" for a more
  175.  *  detailed discussion of these ground rules.
  176.  *
  177.  *  For 16-Bit processors (e.g. 80x86), times for all compilation models
  178.  *  ("small", "medium", "large") should be given if possible, together
  179.  *  with a definition of these models for the compiler system used.
  180.  *
  181.  **************************************************************************
  182.  *
  183.  *  Dhrystone (Pascal version) statistics:
  184.  *
  185.  *  [Comment from the first distribution by Reinhold Weicker,
  186.  *   the distribution statistics have been updated for Version 2.1.
  187.  *   Note that because of language differences, the numbers are different
  188.  *   from the Ada version. The main difference is that the variables that
  189.  *   are local variables of "Proc_0" (Ada) or "main" (C) are global
  190.  *   variables in the Pascal version.]
  191.  *
  192.  *  The following program contains statements of a high level programming
  193.  *  language (here: Pascal) in a distribution considered representative:
  194.  *
  195.  *    assignments                  58
  196.  *    control statements           28
  197.  *    procedure, function calls    15
  198.  *
  199.  *  100 statements are dynamically executed. The program is balanced with
  200.  *  respect to the three aspects:
  201.  *
  202.  *    - statement type
  203.  *    - operand type (for simple data types)
  204.  *    - operand access
  205.  *         operand global, local, parameter, or constant.
  206.  *           There is no static nesting of blocks or procedures,
  207.  *           therefore all variables are either global or local.
  208.  *
  209.  *  The combination of these three aspects is balanced only approximately.
  210.  *
  211.  *  1. Statement Type:
  212.  *  -----------------             number
  213.  *
  214.  *     V1 := V2                   15
  215.  *     V := Constant              12
  216.  *       (incl. V1 := F(..)
  217.  *     Assignment,                 7
  218.  *       with array element
  219.  *     Assignment,                 6
  220.  *       with record component
  221.  *                                --
  222.  *                                40       40
  223.  *
  224.  *     X := Y +|-|and|or Z         5
  225.  *     X := Y +|-|"=" Constant     6
  226.  *     X := X +|- 1                3
  227.  *     X := Y *|/ Z                2
  228.  *     X := Expression,            1
  229.  *          two operators
  230.  *     X := Expression,            1
  231.  *          three operators
  232.  *                                --
  233.  *                                18       18
  234.  *
  235.  *     if .... then ....          14
  236.  *       with "else"      7
  237.  *       without "else"   7
  238.  *           executed        3
  239.  *           not executed    4
  240.  *     for I in 1..N do ...        7  |  counted every time
  241.  *     while ... do ...            4  |  the loop condition
  242.  *     repeat ... until            1  |  is evaluated
  243.  *     case ... end                1
  244.  *     with                        1
  245.  *                                --
  246.  *                                28       28
  247.  *
  248.  *     P (...)  procedure call    10
  249.  *     X := F (...)
  250.  *             function  call      5
  251.  *                                --
  252.  *                                15       15
  253.  *                                        ---
  254.  *                                        101
  255.  *
  256.  *    22 of the 58 assignments have a variable of a constrained
  257.  *    (sub-)type as their destination. In general, discriminant checks
  258.  *    will be necessary in these cases; however, the compiler may
  259.  *    optimize out some of these checks.
  260.  *
  261.  *    The average number of parameters in procedure or function calls
  262.  *    is 1.80 (not counting the function values as implicit parameters).
  263.  *
  264.  *
  265.  *  2. Operators
  266.  *  ------------
  267.  *                          number    approximate
  268.  *                                    percentage
  269.  *
  270.  *    Arithmetic             27          52.9
  271.  *
  272.  *       +                     16          31.4
  273.  *       -                      7          13.7
  274.  *       *                      3           5.9
  275.  *       div                    1           2.0
  276.  *
  277.  *    Comparison             20           39.2
  278.  *
  279.  *       =                      9           17.6
  280.  *       <>                     4            7.8
  281.  *       >                      1            2.0
  282.  *       <                      3            5.9
  283.  *       >=                     1            2.0
  284.  *       <=                     2            3.9
  285.  *
  286.  *    Logic                   4            7.8
  287.  *
  288.  *       AND                    1            2.0
  289.  *       OR                     1            2.0
  290.  *       NOT                    2            3.9
  291.  *
  292.  *                           --          -----
  293.  *                           51           99.9
  294.  *
  295.  *
  296.  *  3. Operand Type (counted once per operand reference):
  297.  *  ---------------
  298.  *                          number    approximate
  299.  *                                    percentage
  300.  *
  301.  *     Integer               135        54.7 %
  302.  *     Character              47        19.0 %
  303.  *     Enumeration            31        12.6 %
  304.  *     Boolean                13         5.3 %
  305.  *     Pointer                11         4.5 %
  306.  *     String30                6         2.4 %
  307.  *     Array                   2         0.8 %
  308.  *     Record                  2         0.8 %
  309.  *                           ---       -------
  310.  *                           247        100.1 %
  311.  *
  312.  *  When there is an access path leading to the final operand (e.g. a record
  313.  *  component), only the final data type on the access path is counted.
  314.  *
  315.  *  There are 16 accesses to components of a record, 9 of them go to
  316.  *  a component in a variant part. For some of these accesses, the
  317.  *  compiler may suppress generation of code checking the tag field
  318.  *  during optimization.
  319.  *
  320.  *
  321.  *  3. Operand Locality:
  322.  *  -------------------
  323.  *
  324.  *     local variable               84        34.0 %
  325.  *     global variable              58        23.5 %
  326.  *     parameter                    45        18.2 %
  327.  *        value                        23         9.3 %
  328.  *        reference                    22         8.9 %
  329.  *     function result               5         2.0 %
  330.  *     constant                     55        22.3 %
  331.  *                                 ---       -------
  332.  *                                 247       100.0 %
  333.  *
  334.  *
  335.  *  The program does not compute anything meaningful, but it is syntactically
  336.  *  and semantically correct. All variables have a value assigned to them
  337.  *  before they are used as a source operand.
  338.  *
  339.  *  There may be cases where a highly optimizing compiler may recognize
  340.  *  unnecessary statements and may not generate code for them.
  341.  *
  342.  *  There has been no explicit effort to account for the effects of a
  343.  *  cache, or to balance the use of long or short displacements for code or
  344.  *  data.
  345.  *
  346.  ****************************************************************************
  347.  *)
  348.  
  349. const (* for measurement *)
  350.  
  351.   MicrosecondsPerClock  = 1000;
  352.   ClocksPerSecond       = 1000;
  353.         (* In Berkeley UNIX Pascal, the function "clock"        *)
  354.         (* returns milliseconds                                 *)
  355.   TooSmallTime          = 2000;
  356.         (* Measurements should last at least 2 seconds          *)
  357.  
  358. type
  359.  
  360.   (* Global type definitions *)
  361.  
  362.   Enumeration           = (Ident1, Ident2, Ident3, Ident4, Ident5);
  363.  
  364.   OneToThirty           = 1..30;
  365.   OneToFifty            = 1..50;
  366.   CapitalLetter         = 'A'..'Z';
  367.  
  368.   String30              = STRING [30];
  369.  
  370.  
  371.   Array1DimInteger      = array [OneToFifty] of integer;
  372.   Array2DimInteger      = array [OneToFifty, OneToFifty] of integer;
  373.  
  374.   RecordPointer         = ^RecordType;
  375.  
  376.   RecordType            =
  377.       record
  378.         PointerComp:   RecordPointer;
  379.         case Discr:    Enumeration of
  380.           Ident1:         (* only this variant is used,           *)
  381.                           (* but in some cases discriminant       *)
  382.                           (* checks are necessary                 *)
  383.             (EnumComp:      Enumeration;
  384.              IntComp:       OneToFifty;
  385.              StringComp:    String30);
  386.           Ident2:
  387.             (Enum2Comp:    Enumeration;
  388.              String2Comp:  String30);
  389.           Ident3, Ident4, Ident5:
  390.             (Char1Comp,
  391.              Char2Comp:    char);
  392.       end; (* record *)
  393.  
  394. var
  395.  
  396.   (* Ada version: Variables local in Proc_0 *)
  397.  
  398.   Int1Glob,
  399.   Int2Glob,
  400.   Int3Glob:       OneToFifty;
  401.   CharIndex:      char;
  402.   EnumGlob:       Enumeration;
  403.   String1Glob,
  404.   String2Glob:    String30;
  405.  
  406.   (* Ada version: Variables global in Pack_1 *)
  407.  
  408.   PointerGlob,
  409.   NextPointerGlob: RecordPointer;
  410.   IntGlob:         integer;
  411.  
  412.   BoolGlob:        boolean;
  413.   Char1Glob,
  414.   Char2Glob:       char;
  415.   Array1Glob:      Array1DimInteger;
  416.   Array2Glob:      Array2DimInteger;
  417.  
  418.   (* Variables for measurement *)
  419.  
  420.   RunIndex,
  421.   NumberOfRuns:         integer;
  422.   BeginClock,
  423.   EndClock,
  424.   SumClocks:            longint;
  425.   Microseconds,
  426.   DhrystonesPerSecond:  real;
  427.   I:                    integer;
  428.  
  429.   (* end of variables for measurement *)
  430.  
  431. procedure Proc1 (    PointerParVal: RecordPointer);     forward;
  432.  
  433. procedure Proc2 (var IntParRef:     OneToFifty);        forward;
  434.  
  435. procedure Proc3 (var PointerParRef: RecordPointer);     forward;
  436.  
  437. procedure Proc4;                                        forward;
  438.   (* without parameters *)
  439.  
  440. procedure Proc5;                                        forward;
  441.   (* without parameters *)
  442.  
  443. procedure Proc6 (    EnumParVal:    Enumeration;
  444.                  var EnumParRef:    Enumeration);       forward;
  445.  
  446. procedure Proc7 (    Int1ParVal,
  447.                      Int2ParVal:    OneToFifty;
  448.                  var IntParRef:     OneToFifty);        forward;
  449.  
  450. procedure Proc8 (var Array1ParRef:  Array1DimInteger;
  451.                  var Array2ParRef:  Array2DimInteger;
  452.                      Int1ParVal,
  453.                      Int2ParVal:    integer);            forward;
  454.  
  455. function Func1  (    Char1ParVal,
  456.                      Char2ParVal:   CapitalLetter):
  457.                                             Enumeration; forward;
  458.  
  459. function Func2  (var String1ParRef,
  460.                      String2ParRef: String30):
  461.                                             boolean;      forward;
  462.  
  463. function Func3  (    EnumParVal:    Enumeration):
  464.                                             boolean;      forward;
  465.  
  466.  
  467. procedure Proc1; (* (PointerParVal: RecordPointer) *)
  468.     (* executed once *)
  469. begin
  470.   with PointerParVal^.PointerComp^ (* = PointerGlobNext *) do
  471.   begin
  472.     PointerParVal^.PointerComp^ := PointerGlob^;
  473.     PointerParVal^.IntComp := 5;
  474.     IntComp := PointerParVal^.IntComp;
  475.     PointerComp := PointerParVal^.PointerComp;
  476.     Proc3 (PointerComp);
  477.       (* PointerParVal^.PointerComp^.PointerComp = PointerGlob^.PointerComp *)
  478.     if Discr = Ident1
  479.     then (* executed *)
  480.     begin
  481.       IntComp := 6;
  482.       Proc6 (PointerParVal^.EnumComp, EnumComp);
  483.       PointerComp := PointerGlob^.PointerComp;
  484.       Proc7 (IntComp, 10, IntComp);
  485.     end (* then *)
  486.     else (* not executed *)
  487.       PointerParVal^ := PointerParVal^.PointerComp^;
  488.   end; (* with *)
  489. end; (* Proc1 *)
  490.  
  491.  
  492. procedure Proc2; (* (var IntParRef: OneToFifty) *)
  493.     (* executed once *)
  494.     (* InParRef = 3, becomes 7 *)
  495. var
  496.   IntLoc:  OneToFifty;
  497.   EnumLoc: Enumeration;
  498. begin
  499.   IntLoc := IntParRef + 10;
  500.   repeat (* executed once *)
  501.     if Char1Glob = 'A'
  502.     then (* executed *)
  503.     begin
  504.       Dec (IntLoc);
  505.       IntParRef := IntLoc - IntGlob;
  506.       EnumLoc := Ident1;
  507.     end (* if *)
  508.   until EnumLoc = Ident1; (* true *)
  509. end; (* Proc2 *)
  510.  
  511.  
  512. procedure Proc3; (* (var PointerParRef: RecordPointer) *)
  513.     (* executed once *)
  514.     (* PointerParRef becomes PointerGlob *)
  515. begin
  516.   if PointerGlob <> nil
  517.   then (* executed *)
  518.     PointerParRef := PointerGlob^.PointerComp;
  519.   Proc7 (10, IntGlob, PointerGlob^.IntComp);
  520. end; (* Proc3 *)
  521.  
  522.  
  523. procedure Proc4; (* without parameters *)
  524.     (* executed once *)
  525. var
  526.   BoolLoc: boolean;
  527. begin
  528.   BoolLoc := Char1Glob = 'A';
  529.   BoolGlob := BoolLoc or BoolGlob;
  530.   Char2Glob := 'B';
  531. end; (* Proc4 *)
  532.  
  533.  
  534. procedure Proc5; (* without parameters *)
  535.     (* executed once *)
  536. begin
  537.   Char1Glob := 'A';
  538.   BoolGlob := false;
  539. end; (* Proc5 *)
  540.  
  541.  
  542. procedure Proc6; (* (    EnumParVal:     Enumeration;
  543.                      var EnumParRef:     Enumeration) *)
  544.     (* executed once *)
  545.     (* EnumParVal = Ident3, EnumParRef becomes Ident2 *)
  546. begin
  547.   EnumParRef := EnumParVal;
  548.   if not Func3 (EnumParVal)
  549.   then (* not executed *)
  550.     EnumParRef := Ident4;
  551.   case EnumParVal of
  552.     Ident1: EnumParRef := Ident1;
  553.     Ident2: if IntGlob > 100
  554.               then EnumParRef := Ident1
  555.               else EnumParRef := Ident4;
  556.     Ident3: EnumParRef := Ident2;    (* executed *)
  557.     Ident4: ;
  558.     Ident5: EnumParRef := Ident3;
  559.   end; (* case *)
  560. end; (* Proc6 *)
  561.  
  562.  
  563. procedure Proc7; (* (    Int1ParVal,
  564.                          Int2ParVal:    OneToFifty;
  565.                      var IntParRef:     OneToFifty) *)
  566.     (* executed three times                               *)
  567.     (* first call:      Int1ParVal = 2, Int2ParVal = 3,   *)
  568.     (*                  IntParRef becomes 7               *)
  569.     (* second call:     Int1ParVal = 10, Int2ParVal = 5,  *)
  570.     (*                  IntParRef becomes 17              *)
  571.     (* third call:      Int1ParVal = 6, Int2ParVal = 10,  *)
  572.     (*                  IntParRef becomes 18              *)
  573. var
  574.   IntLoc: OneToFifty;
  575. begin
  576.   IntLoc := Int1ParVal + 2;
  577.   IntParRef := Int2ParVal + IntLoc;
  578. end; (* Proc7 *)
  579.  
  580.  
  581. procedure Proc8; (* (var Array1ParRef: Array1DimInteger;
  582.                      var Array2ParRef: Array2DimInteger;
  583.                          Int1ParVal,
  584.                          Int2ParVal:    integer)          *)
  585.     (* executed once  *)
  586.     (* Int1ParVal = 3 *)
  587.     (* Int2ParVal = 7 *)
  588. var
  589.   IntIndex,
  590.   IntLoc:   OneToFifty;
  591. begin
  592.   IntLoc := Int1ParVal + 5;
  593.   Array1ParRef [IntLoc] := Int2ParVal;
  594.   Array1ParRef [IntLoc+1] := Array1ParRef [IntLoc];
  595.   Array1ParRef [IntLoc+30] := IntLoc;
  596.   for IntIndex := IntLoc to IntLoc+1 do
  597.     Array2ParRef [IntLoc, IntIndex] := IntLoc;
  598.   Array2ParRef [IntLoc, IntLoc-1] := Array2ParRef [IntLoc, IntLoc-1] + 1;
  599.   Array2ParRef [IntLoc+20, IntLoc] := Array1ParRef [IntLoc];
  600.   IntGlob := 5;
  601. end; (* Proc8 *)
  602.  
  603.  
  604. function Func1; (* (Char1ParVal,
  605.                     Char2ParVal: CapitalLetter): Enumeration *)
  606.     (* executed three times, returns always Ident1              *)
  607.     (* first call:      Char1ParVal = 'H', Char2ParVal = 'R'    *)
  608.     (* second call:     Char1ParVal = 'A', Char2ParVal = 'C'    *)
  609.     (* third call:      Char1ParVal = 'B', Char2ParVal = 'C'    *)
  610. var
  611.   Char1Loc, Char2Loc: CapitalLetter;
  612. begin
  613.   Char1Loc := Char1ParVal;
  614.   Char2Loc := Char1Loc;
  615.   if Char2Loc <> Char2ParVal
  616.   then  (* executed *)
  617.     Func1 := Ident1
  618.   else  (* not executed *)
  619.   begin
  620.     Char1Glob := Char1Loc;
  621.     Func1 := Ident2;
  622.   end;
  623. end; (* Func1 *)
  624.  
  625.  
  626. function Func2; (* (var String1ParRef,
  627.                         String2ParRef: String30): boolean *)
  628.     (* executed once, returns false              *)
  629.     (* String1ParRef = 'DHRYSTONE PROGRAM, 1''ST STRING' *)
  630.     (* String2ParRef = 'DHRYSTONE PROGRAM, 2''ND STRING' *)
  631. var
  632.   IntLoc:  OneToThirty;
  633.   CharLoc: CapitalLetter;
  634. begin
  635.   IntLoc := 2;
  636.   while IntLoc <= 2 do (* loop body executed once *)
  637.     if Func1 (String1ParRef[IntLoc],
  638.               String2ParRef[IntLoc+1]) = Ident1
  639.     then (* executed *)
  640.     begin
  641.       CharLoc := 'A';
  642.       Inc (IntLoc);
  643.     end; (* if, while *)
  644.   if (CharLoc >= 'W') and (CharLoc < 'Z')
  645.   then (* not executed *)
  646.     IntLoc := 7;
  647.   if CharLoc = 'R'
  648.   then (* not executed *)
  649.     Func2 := true
  650.   else (* executed *)
  651.   begin
  652.     if String1ParRef > String2ParRef
  653.     then (* not executed *)
  654.     begin
  655.       IntLoc := IntLoc + 7;
  656.       IntGlob := IntLoc;
  657.       Func2 := true
  658.     end
  659.     else (* executed *)
  660.       Func2 := false;
  661.   end; (* if CharLoc *)
  662. end; (* Func2 *)
  663.  
  664.  
  665. function Func3; (* (EnumParVal: Enumeration): boolean *)
  666.     (* executed once, returns true      *)
  667.     (* EnumParVal = Ident3              *)
  668. var
  669.   EnumLoc:  Enumeration;
  670. begin
  671.   EnumLoc := EnumParVal;
  672.   if EnumLoc = Ident3
  673.   then (* executed *)
  674.     Func3 := true
  675.   else (* not executed *)
  676.     Func3 := false;
  677. end; (* Func3 *)
  678.  
  679. FUNCTION Dhrystones (Index: DOUBLE): DOUBLE;
  680. begin (* main program, corresponds to procedures        *)
  681.       (* Main and Proc_0 in the Ada version             *)
  682.  
  683.   (* Initializations *)
  684.  
  685.   new (NextPointerGlob);
  686.  
  687.   new (PointerGlob);
  688.  
  689.   PointerGlob^.PointerComp := NextPointerGlob;
  690.   PointerGlob^.Discr       := Ident1;
  691.   PointerGlob^.EnumComp    := Ident3;
  692.   PointerGlob^.IntComp     := 40;
  693.   PointerGlob^.StringComp  := 'DHRYSTONE PROGRAM, SOME STRING';
  694.  
  695.   String1Glob := 'DHRYSTONE PROGRAM, 1''ST STRING';
  696.  
  697.   Array2Glob [8,7] := 10;
  698.  
  699.   NumberofRuns := Round (200 * (Index / 3 + 1));
  700.  
  701.   BeginClock := Clock;
  702.  
  703.   (***************)
  704.   (* Start timer *)
  705.   (***************)
  706.  
  707.   for RunIndex := 1 to NumberOfRuns do
  708.   begin
  709.  
  710.     Proc5;
  711.     Proc4;
  712.       (* Char1Glob = 'A', Char2Glob = 'B', BoolGlob = false *)
  713.     Int1Glob := 2;
  714.     Int2Glob := 3;
  715.     String2Glob := 'DHRYSTONE PROGRAM, 2''ND STRING';
  716.     EnumGlob := Ident2;
  717.     BoolGlob := not Func2 (String1Glob, String2Glob);
  718.       (* BoolGlob = true *)
  719.     while Int1Glob < Int2Glob do  (* loop body executed once *)
  720.     begin
  721.       Int3Glob := 5 * Int1Glob - Int2Glob;
  722.         (* Int3Glob = 7 *)
  723.       Proc7 (Int1Glob, Int2Glob, Int3Glob);
  724.         (* Int3Glob = 7 *)
  725.       Inc (Int1Glob);
  726.     end; (* while *)
  727.       (* Int1Glob = 3 *)
  728.     Proc8 (Array1Glob, Array2Glob, Int1Glob, Int3Glob);
  729.       (* IntGlob = 5 *)
  730.     Proc1 (PointerGlob);
  731.     for CharIndex := 'A' to Char2Glob do   (* loop body executed twice *)
  732.       if EnumGlob = Func1 (CharIndex, 'C')
  733.         then (* not executed *)
  734.         begin
  735.           Proc6 (Ident1, EnumGlob);
  736.           String2Glob := 'DHRYSTONE PROGRAM, 3''RD STRING';
  737.           Int2Glob := RunIndex;
  738.           IntGlob := RunIndex;
  739.         end;
  740.     (* Int1Glob = 3, Int2Glob = 3, Int3Glob = 7 *)
  741.     Int2Glob := Int2Glob * Int1Glob;
  742.     Int1Glob := Int2Glob div Int3Glob;
  743.     Int2Glob := 7 * (Int2Glob - Int3Glob) - Int1Glob;
  744.       (* Int1Glob = 1, Int2Glob = 13, Int3Glob = 7 *)
  745.     Proc2 (Int1Glob);
  746.       (* Int1Glob = 5 *)
  747.  
  748.   end; (* for RunIndex *)
  749.  
  750.   EndClock := Clock;
  751.  
  752.   (**************)
  753.   (* Stop timer *)
  754.   (**************)
  755.  
  756.  
  757.   SumClocks := EndClock - BeginClock;
  758.  
  759.   Dhrystones := NumberOfRuns * (ClocksPerSecond / SumClocks);
  760.  
  761. end;
  762.  
  763. end.
  764.